package com.leonzx.base.controller;

import com.leonzx.base.controller.base.BaseController;
import com.leonzx.base.entity.system.Menu;
import com.leonzx.base.entity.system.User;
import com.leonzx.base.service.RedisService;
import com.leonzx.base.service.system.MenuService;
import com.leonzx.base.utils.Constants;
import com.leonzx.base.utils.HttpUtils;
import com.leonzx.base.utils.RedisConstants;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @Author:梁亮
 * @Description: 登录相关
 * @Date: 2018/5/2 17:02
 */
@Controller
@RequestMapping("/")
public class LoginController extends BaseController {
    @Value("${jim.serviceIp}")
    private String serviceIp;

    @Value("${jim.port}")
    public Integer port;

    @Autowired
    private MenuService menuService;

    @Autowired
    private RedisService redisService;

    @RequestMapping("/login")
    public String login(String code, String ip, String repeat, Model model) {
        String msg;
        if (Objects.equals(repeat, "1")) {
            msg = "已重复登录，登录IP:" + ip + "。<br>非本人操作，请联系管理员";
        } else {
            msg = "已被强制下线，如有疑问，请联系管理员";
        }
        model.addAttribute("msg", msg);
        model.addAttribute("code", code);
        return "login";
    }

    @RequestMapping(value = "/loginInput", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> loginInput(User user, HttpServletRequest request) {
        Map<String, Object> result = getMap();
        try {
            // shiro认证
            UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(user.getUsername(), user.getPassword());
            SecurityUtils.getSubject().login(usernamePasswordToken);
            User loginUser = (User) SecurityUtils.getSubject().getPrincipal();
            // 缓存登录时间
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            redisService.setKey(RedisConstants.SHIRO_REDIS_USER_LOGIN_TIME + ":" + loginUser.getUsername(), simpleDateFormat.format(new Date()));
            String ip = HttpUtils.getIpAddress(request);
            redisService.setKey(RedisConstants.SHIRO_REDIS_USER_LOGIN_IP + ":" + loginUser.getUsername(), ip);
            redisService.setKey(RedisConstants.SHIRO_REDIS_USER_LOGIN_MENU + ":" + loginUser.getUsername(), loginUser.getMenuPosition() + "");
            addSuccessMessage(result, "登录成功");
        } catch (UnknownAccountException e) {
            addFailMessage(result, e.getMessage());
            logger.error("登录失败", e);
        } catch (LockedAccountException e) {
            addFailMessage(result, e.getMessage());
            logger.error("登录失败", e);
        } catch (AuthenticationException e) {
            addFailMessage(result, "用户名密码不正确！");
            logger.error("登录失败", e);
        } catch (Exception e) {
            addFailMessage(result, e.getMessage());
            logger.error("登录失败", e);
        }
        return result;
    }

    @RequestMapping("/index")
    public String index(Model model) {
        List<Menu> menus = menuService.getRootMenuByIds(currentUser().getId());
        model.addAttribute("serviceIp", serviceIp);
        model.addAttribute("port", port);
        model.addAttribute("menus", menus);
        String menuPostion = redisService.getValue(RedisConstants.SHIRO_REDIS_USER_LOGIN_MENU + ":" + currentUser().getUsername());
        if (Objects.equals(Constants.MENU_POSITION_TOP + "", menuPostion)) {
            return "top-menu-index";
        }
        return "left-menu-index";
    }

    @RequestMapping("/")
    public String top() {
        return "redirect:/index";
    }

    @RequestMapping("/kickout")
    public String kickout(String username, String repeat) {
        String ip = redisService.getValue(RedisConstants.SHIRO_REDIS_USER_LOGIN_IP + ":" + username);
        return "redirect:/login?code=9&ip=" + ip + "&repeat=" + repeat;
    }
}
